﻿using System;
using System.Linq;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;
using LinqKit;
using Syncfusion.Windows.Forms.Grid;
using Syncfusion.Windows.Forms.Grid.Grouping;
using Syncfusion.GridExcelConverter;
using Syncfusion.GroupingGridExcelConverter;

using PMngr.Data;

namespace PMngr.Main
{
    public partial class TransferReport : BaseControl
    {
        private IRepositoryFactory repositoryFactory;

        public TransferReport()
        {
            InitializeComponent();
            InitializeGridGrouping();

            this.dtFrom.Value = DateTime.Today.AddDays(-7);
            this.dtTo.Value = DateTime.Today;
        }

        public TransferReport(IRepositoryFactory repositoryFactory)
            : this()
        {
            this.repositoryFactory = repositoryFactory;
        }

        public override void InitializeControls()
        {
            InitializeUnitType();
            InitializeUpUnitComboBox();
            InitializeCauseComboBox();

            comUnitType.SelectedIndexChanged += new System.EventHandler(this.comUnitType_SelectedIndexChanged);

            btnSearch_Click(this, EventArgs.Empty);
        }

        private void InitializeCauseComboBox()
        {
            using (var repository = repositoryFactory.CreateRepository())
            {
                var options = repository.All<ItemBase>();
                var datasource = from o in options
                                 where o.Type == "TransCause" && o.IsValid
                                 orderby o.Order
                                 select new { o.Code, o.Name };
                var result = datasource.ToList();
                result.Insert(0, new { Code = DefaultNull.DefaultValue, Name = DefaultNull.DefaultName });
                comCause.DataSource = result;
                comCause.DisplayMember = "Name";
                comCause.ValueMember = "Code";
            }
        }

        private void InitializeUnitType()
        {
            using (var repository = repositoryFactory.CreateRepository())
            {
                // 单位区域
                var options = repository.All<ItemBase>();
                var datasource = from o in options
                                 where o.Type == "UnitType" && o.IsValid == true
                                 orderby o.Order ascending
                                 select new {Code = o.Code, Name = o.Name};
                var result = datasource.ToList();
                result.Insert(0, new {Code = DefaultAll.DefaultValue, Name = DefaultAll.DefaultName});
                comUnitType.DataSource = result;
                comUnitType.DisplayMember = ItemModel.GetPropertyName(u => u.Name);
                comUnitType.ValueMember = ItemModel.GetPropertyName(u => u.Code);
            }
        }

        private void InitializeUpUnitComboBox()
        {
            using (var repository = repositoryFactory.CreateRepository())
            {
                // 主管部门
                var units = repository.Find<Unit>(u => u.IsValid && u.ParentUnit == null);
                var datasource = from u in units
                                 select new {Id = u.Id, Name = u.Name};

                var result = datasource.ToList();
                result.Insert(0, new {Id = DefaultAll.DefaultValue, Name = DefaultAll.DefaultName});
                comUpUnit.DataSource = result;
                comUpUnit.DisplayMember = UnitModel.GetPropertyName(u => u.Name);
                comUpUnit.ValueMember = UnitModel.GetPropertyName(u => u.Id);
            }
            // settings
            GridControl grid = comUpUnit.ListBox.Grid;
            grid.Cols.DefaultSize = 230;
            grid.HideCols[UnitModel.GetPropertyName(u => u.Id)] = true;
            grid.PrepareViewStyleInfo += new GridPrepareViewStyleInfoEventHandler(gridListUp_PrepareViewStyleInfo);
        }

        private void gridListUp_PrepareViewStyleInfo(object sender, GridPrepareViewStyleInfoEventArgs e)
        {
            if (e.ColIndex == 2 && e.RowIndex == 0)
            {
                e.Style.Text = Utilities.MajorUnitSelected;
            }
        }

        private void comUnitType_SelectedIndexChanged(object sender, EventArgs e)
        {
            var unitType = comUnitType.SelectedValue;
            // 单位
            if ((int)unitType == -1)
            {
                InitializeUpUnitComboBox();
            }
            else
            {
                using (var repository = repositoryFactory.CreateRepository())
                {
                    var units =
                        repository.Find<Unit>(
                            u => u.IsValid && u.ParentUnit == null && u.UnitType.Code == (int) unitType);
                    var datasource = from u in units
                                     select new {Id = u.Id, Name = u.Name};

                    var result = datasource.ToList();
                    result.Insert(0, new {Id = DefaultAll.DefaultValue, Name = DefaultAll.DefaultName});
                    comUpUnit.DataSource = result;
                    comUpUnit.DisplayMember = UnitModel.GetPropertyName(u => u.Name);
                    comUpUnit.ValueMember = UnitModel.GetPropertyName(u => u.Id);
                }
            }
        }

        private void InitializeGridGrouping()
        {
            foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(typeof(ProfileReport)))
            {
                GridColumnDescriptor gcd = new GridColumnDescriptor(pd.Name, pd.Name, ProfileReport.Dict[pd.Name], true);
                this.gridList.TableDescriptor.Columns.Add(gcd);
            }

            this.gridList.TableDescriptor.VisibleColumns.Remove(ProfileReport.GetPropertyName(u => u.WholeTransferId));  

            this.gridList.TableDescriptor.Name = @"调动人员";
            this.gridList.TableDescriptor.FrozenColumn = ProfileReport.GetPropertyName(u => u.Name);

            gridList.InitializeGridGrouping();
            gridList.Appearance.AlternateRecordFieldCell.Interior = gridList.Appearance.RecordFieldCell.Interior;
            // caption);
            this.gridList.TopLevelGroupOptions.ShowCaption = true;
            this.gridList.TopLevelGroupOptions.CaptionText = Utilities.CategoryCaption;
            this.gridList.ChildGroupOptions.CaptionText = Utilities.CategoryCaption;
            // group drop
            this.gridList.ShowGroupDropArea = true;
            this.gridList.GridGroupDropArea.DragColumnHeaderText = Utilities.Grouping;
            
            gridList.DataSource = bindingSource;
            // event
            gridList.QueryCellStyleInfo += GridGroupingControl1QueryCellStyleInfo;
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            var fromDate = dtFrom.Value.FromDate();
            var toDate = dtTo.Value.ToDate();
            var name = txtName.Text;

            var predicate = PredicateBuilder.True<Profile>();
            // 审批标志
            var approvalPredicate = PredicateBuilder.False<Profile>();
            if (chkApproved.Checked)
                approvalPredicate = approvalPredicate.Or(p => p.ApprovalDate != null);
            if (chkApproving.Checked)
                approvalPredicate = approvalPredicate.Or(p => p.ApprovalDate == null);
            predicate = predicate.And(approvalPredicate.Expand());
            // 调动类型
            var transPredicate = PredicateBuilder.False<Profile>();
            if (chkIn.Checked)
                transPredicate = transPredicate.Or(p => p.TransferKind == false);
            if (chkOut.Checked)
                transPredicate = transPredicate.Or(p => p.TransferKind == true);
            predicate = predicate.And(transPredicate.Expand());
            //           
            var defaultValue = DefaultAll.DefaultValue;
            // 单位区域
            var unitType = comUnitType.SelectedValue;
            if ((int)unitType != defaultValue)
                predicate = predicate.And(p=>p.InUnit.ParentUnit.UnitType.Code == (int)unitType);
            // 主管部门
            var upUnit = comUpUnit.Text;
            if (upUnit != DefaultAll.DefaultName)
                predicate = predicate.And(p => p.InUnit.ParentUnit.Name.Contains(upUnit));
            // 调动理由
            var transferCause = comCause.SelectedValue;
            if ((int)transferCause != defaultValue)
                predicate = predicate.And(p => p.TransferReason.Code == (int)transferCause);
            // 姓名
            if (!String.IsNullOrWhiteSpace(name))
                predicate = predicate.And(p => p.Name.Contains(name));

            predicate = predicate.And(p => p.RecordDate >= fromDate && p.RecordDate <= toDate);

            using (var repository = repositoryFactory.CreateRepository())
            {
                var dataSource = repository.Find<Profile>(predicate.Expand()).Select(p => new ProfileReport
                                                                                              {
                                                                                                  Name = p.Name,
                                                                                                  Nationality =
                                                                                                      p.Nationality,
                                                                                                  BirthDate =
                                                                                                      p.BirthDate,
                                                                                                  Gender = p.Gender,
                                                                                                  Family = p.Family,
                                                                                                  SchoolRecord =
                                                                                                      p.SchoolRecord.
                                                                                                      Name,
                                                                                                  SchoolLevel =
                                                                                                      p.SchoolLevel.Name,
                                                                                                  PolicyFace =
                                                                                                      p.PolicyFace.Name,
                                                                                                  MarriedDate =
                                                                                                      p.MarriedDate,
                                                                                                  College = p.College,
                                                                                                  Major = p.Major,
                                                                                                  InUnit = p.OriginalIn,
                                                                                                  InUnitMajor =
                                                                                                      p.OriginalInUpUnit,
                                                                                                  InUnitType =
                                                                                                      p.
                                                                                                      OriginalInUnitType,
                                                                                                  InUnitKind =
                                                                                                      p.
                                                                                                      OriginalInUnitKind,
                                                                                                  OutUnit =
                                                                                                      p.OriginalOut,
                                                                                                  OutUnitMajor =
                                                                                                      p.
                                                                                                      OriginalOutUpUnit,
                                                                                                  OutUnitType =
                                                                                                      p.
                                                                                                      OriginalOutUnitType,
                                                                                                  OutUnitKind =
                                                                                                      p.
                                                                                                      OriginalOutUnitKind,
                                                                                                  ProfPos = p.ProfPos,
                                                                                                  ProfTitle =
                                                                                                      p.ProfTitle,
                                                                                                  PersonalIdentity =
                                                                                                      p.PersonalIdentity
                                                                                                      .Name,
                                                                                                  TechGrade =
                                                                                                      p.TechGrade.Name,
                                                                                                  WorkKind = p.WorkKind,
                                                                                                  WorkStart =
                                                                                                      p.WorkStart,
                                                                                                  TransferReason =
                                                                                                      p.TransferReason.
                                                                                                      Name,
                                                                                                  SalaryGrade =
                                                                                                      p.SalaryGrade,
                                                                                                  RecordDate =
                                                                                                      p.RecordDate,
                                                                                                  Remark1 = p.Remark1,
                                                                                                  Remark2 = p.Remark2,
                                                                                                  WholeTransferId =
                                                                                                      p.WholeTransfer.Id,
                                                                                                  ApprovalDate =
                                                                                                      p.ApprovalDate
                                                                                              });

                var result = dataSource.ToList();
                bindingSource.DataSource = result;
            }
        }        

        private void ExcelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Files(*.xls)|*.xls";
            saveFileDialog.FileName = String.Format("{0}.xls", DateTime.Now.ToString("yyyyMMddhhmmss"));
            saveFileDialog.AddExtension = true;
            saveFileDialog.DefaultExt = ".xls";

            if (saveFileDialog.ShowDialog() == DialogResult.OK && saveFileDialog.CheckPathExists)
            {
                gridList.ExportToExcel(saveFileDialog.FileName);

                if (MessageFactory.MessageBoxShow(Utilities.OpenExcelConfirmed) == DialogResult.Yes)
                {
                    var proc = new System.Diagnostics.Process {StartInfo = {FileName = saveFileDialog.FileName}};
                    proc.Start();
                }
            }
        }       

        private void comUpUnit_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.Handled == false)
            {
                if (this.comUpUnit.DroppedDown == false)
                {
                    this.comUpUnit.DroppedDown = true;
                }
            }
            else
            {
                this.comUpUnit.DroppedDown = false;
            }
        }

        private static readonly Color[] colors = new Color[] 
            {  
                Color.FromArgb(41,158,214),
                Color.FromArgb(206,215,41),
                Color.FromArgb(250,236,35),
                Color.FromArgb(155,166,184),
                Color.FromArgb(255,146,140),
                Color.FromArgb(180,192,98),
                Color.FromArgb(247,125,16)         
            };

        private static void GridGroupingControl1QueryCellStyleInfo(object sender, GridTableCellStyleInfoEventArgs e)
        {
            // format the datetime field
            if (e.Style.CellValueType == typeof(DateTime) || e.Style.CellValueType == typeof(DateTime?))
            {
                if (e.TableCellIdentity.Column.Name != ProfileReport.GetPropertyName(p=>p.RecordDate) && e.TableCellIdentity.Column.Name != ProfileReport.GetPropertyName(p => p.ApprovalDate))
                    e.Style.Format = "d";
            }

            if (e.TableCellIdentity.TableCellType == GridTableCellType.RecordFieldCell || e.TableCellIdentity.TableCellType == GridTableCellType.AlternateRecordFieldCell)
            {
                var row = e.TableCellIdentity.DisplayElement.GetData() as ProfileReport;
                if (row == null) return;

                if (!row.WholeTransferId.HasValue) return;

                var wholeId = row.WholeTransferId.Value;

                var index = wholeId % 7;
                var color = colors[index];
                e.Style.BackColor = color;
            }
            e.Handled = true;
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Enter)
            {
                btnSearch_Click(this,EventArgs.Empty);
                return true;
            }

            return base.ProcessCmdKey(ref msg, keyData);
        }       
    }

}
